/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import comunicacao.AppDatabaseComunicator;
import comunicacao.GestorZooKeeper;
import comunicacao.RmiAppInterface;
import entities.Resposta;
import entities.Teatro;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;

/**
 *
 * @author Leonardo Lino Nº45340
 * @author Diogo Pires Nº40351
 */
public class RecebeComunicacao extends java.rmi.server.UnicastRemoteObject
        implements RmiAppInterface {

    private int thisPort;
    private String thisAddress = "127.0.0.1";
    Registry registry; // rmi registry for lookup the remote objects.
    AppDatabaseComunicator appDB;
    Principal prin;
    GestorReservas reservas;
    ConfigGeral cg = new ConfigGeral();
    private GestorZooKeeper gzk;
    

    public RecebeComunicacao(Principal principal ) throws RemoteException {
        this.prin = principal;
        setPortIP();

        
        prin.dbInfoLabel.setText(ConfigGeral.CG_SERVER_DB_IP + ":" + ConfigGeral.CG_SERVER_DB_PORT);
        //appDB = new AppDatabaseComunicator(ConfigGeral.CG_SERVER_DB_IP, Integer.toString(ConfigGeral.CG_SERVER_DB_PORT));
        
    }

    public void startRecebe() throws RemoteException {
        reservas = new GestorReservas(prin, gzk);

        

        prin.appinfoLabel.setText(this.thisAddress + ":" + thisPort);
        System.out.println("this address=" + thisAddress + ",port=" + thisPort);

        try {
            // create the registry and bind the name and object.
            registry = LocateRegistry.createRegistry(thisPort);
            registry.rebind(ConfigGeral.CG_SERVER_APP_NAME, this);

        } catch (RemoteException e) {
            System.err.println(e);
        }

    }

    private void setPortIP() {
        thisAddress = ConfigGeral.CG_SERVER_APP_IP;
        int portAtual = ConfigGeral.CG_SERVER_APP_PORT;
        thisPort = portAtual;

        while (!cg.availablePort(portAtual)) {
            portAtual++;
            thisPort = portAtual;
        }

    }

    @Override
    public Resposta listTheaters() throws RemoteException {
        Resposta resposta = null;
        prin.consola.append("LISTA TEATRO \n");

        ArrayList<String> lista = reservas.listTheaters();

        if (lista != null) {
            resposta = new Resposta();
            resposta.setEstado(Resposta.ESTADO_AVAILABLE);
            resposta.setTeatrosLista(lista);
        }
        return resposta;

    }

    @Override
    public Resposta getTheater(String theaterName) throws RemoteException {

        Resposta resposta = null;

        Teatro teatro = reservas.getTheater(theaterName);

        if (teatro != null) {
            resposta = new Resposta();
            resposta.setEstado(Resposta.ESTADO_AVAILABLE);
            resposta.setTeatro(teatro);
        }

        return resposta;
    }

    @Override
    public Resposta reserveSeat(String theaterName, int lugarID, int userID) throws RemoteException {

        Resposta resposta = null;
        Teatro teatro = reservas.addReserva(theaterName, lugarID, userID);

        if (teatro != null) {
            resposta = new Resposta();
            resposta.setEstado(Resposta.ESTADO_AVAILABLE);
            resposta.setTeatro(teatro);
        }
        return resposta;
    }

    @Override
    public Resposta purchaseSeat(String theaterName, int lugarID, int userID) throws RemoteException {
        Resposta resposta = null;

        Teatro teatro = reservas.compraLugar(theaterName, lugarID, userID);

        resposta = new Resposta();
        if (teatro != null) {

            resposta.setEstado(Resposta.ESTADO_AVAILABLE);
            resposta.setTeatro(teatro);
        } else {
            resposta.setEstado(Resposta.ESTADO_BADCOMPRA);
            resposta.setTeatro(reservas.getTheater(theaterName));
        }
        return resposta;
    }

    public int getThisPort() {
        return thisPort;
    }

    public String getThisAddress() {
        return thisAddress;
    }

    @Override
    public boolean falha() throws RemoteException {
        prin.consola.append("FALHA ------ \n");
        registry.rebind(ConfigGeral.CG_SERVER_APP_NAME + "temp", this);
        return true;
    }

    @Override
    public boolean restart() throws RemoteException {
        prin.consola.append("RESTART ------ \n");
        registry.rebind(ConfigGeral.CG_SERVER_APP_NAME, this);
        return true;
    }

    public void setGzk(GestorZooKeeper gzk) {
        this.gzk = gzk;
    }
    
    

}
